【Swift】CollectionViewで選択中のセルを強調させる方法
CollectionViewで選択中のセルを強調させたかったのでその方法について調べました。
環境
- Xcode 14.1
- iOS 16.1
はじめに
今回は選択中のセルを強調させるという内容になっている為、UICollectionView
の設定方法などは記載しておりません。
selectedBackgroundViewを使用する
UICollectionViewCell
はselectedBackgroundView
というプロパティを持っており、このプロパティは、セルが選択されるとセル自身のBackground Viewの上に表示されるViewです。
使用例
UserCell
import UIKit class UserCell: UICollectionViewCell { func setup() { self.layer.masksToBounds = true self.layer.cornerRadius = self.layer.frame.height / 2 // セルの背景色を設定 self.backgroundColor = .systemGray5 // セルが選択された時に表示するBackgroundViewを作成 let selectedBackgroundView = UIView() selectedBackgroundView.backgroundColor = .systemYellow // 作成したBackgroundViewをセルが選択された時のViewに設定 self.selectedBackgroundView = selectedBackgroundView } }
ViewController: UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "UserCell", for: indexPath) as? UserCell else { fatalError() } cell.setup() return cell }
デモ
ただし、この方法だとセル自身の背景Viewの上にselectedBackgroundView
を重ねて表示させている為、イメージが不透明の場合だとselectedBackgroundView
に切り替わったとしても選択中の色を確認することが出来ません。
また、セル全体のselectedBackgroundView
になる為、画像とユーザー名があるようなセルで、画像の部分だけ強調をさせたい時には不向きに感じました。
isSelectedの値の変更時に独自の選択Viewの状態を切り替える
これまではselectedBackgroundView
を表示するやり方でしたが、今回は選択状態を切り替えるViewを作成し、UICollectionViewCell
のisSelected
の値の変化時にその選択状態を切り替えるViewの状態を変更する方法です。
使用例
UserProfileCell
セルの中に、選択状態を表現する為のProfileImageFrameView
とユーザー画像用のUIImageView
、ユーザー名用のUILabel
があります。
import UIKit class UserProfileCell: UICollectionViewCell { @IBOutlet weak var profileImageFrameView: UIView! private let selectedFrameColor: CGColor = UIColor.tintColor.cgColor private let defaultFrameColor: CGColor = UIColor.systemGray5.cgColor override func awakeFromNib() { super.awakeFromNib() } override var isSelected: Bool { didSet { // 選択状態が切り替わった時に実行される self.profileImageFrameView.layer.borderColor = isSelected ? selectedFrameColor : defaultFrameColor } } func setup() { profileImageFrameView.layer.borderWidth = 1 profileImageFrameView.layer.borderColor = defaultFrameColor profileImageFrameView.layer.cornerRadius = profileImageFrameView.layer.frame.height / 2 } }
isSelected
がUICollectionViewCell
の選択状態のプロパティで、セルが選択されるとこの値が変更されます。なので、didSet
で値が変更された際に、選択中ならばprofileImageFrameView
のborderColor
を選択中のカラーに変更し、選択されていない場合はデフォルトのborderColor
を設定しています。
ViewController: UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "UserProfileCell", for: indexPath) as? UserProfileCell else { fatalError() } cell.setup() return cell }
デモ
おわりに
UICollectionViewCell
を選択状態によって、見た目を変更することが出来ました。isSelected
だけではなく、isHighlighted
というハイライト状態も取得できる為、ハイライトされている時も見た目を変更するのは良いかもしれません。
まだ他に選択状態を変更する良い方法あれば教えていただければと思います。
この記事が誰かの助けになれば嬉しいです。